#!/usr/bin/env python3
# coding: utf-8
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import json
from .graph import Graph


def set_ops_and_tensors_in_one_graph(op_info, g):
    for j in range(len(op_info['output_desc'])):
        if op_info['output_desc'][j]['tensor_name'] not in g.tensors:
            continue
        g.ops.append(op_info)
        for input_info in op_info['input_desc']:
            for sub_input_info in input_info:
                g.tensors.add(sub_input_info['tensor_name'])


def set_ops_and_tensors(desc_d, sub_graphs):
    # traversal desc_d by reverse topological order to construct subgraph
    for i in range(len(desc_d['op_desc']) - 1, -1, -1):
        op_info = desc_d['op_desc'][i]
        for g in sub_graphs:
            set_ops_and_tensors_in_one_graph(op_info, g)


def set_input(desc_d, sub_graphs):
    # get subgraph original input
    if desc_d['input_desc'] is None:
        return
    for op_input in desc_d['input_desc']:
        for g in sub_graphs:
            if op_input[0]['tensor_name'] in g.tensors:
                g.input.append(op_input)


def set_output(desc_d, sub_graphs):
    # get subgraph original output
    for op_output in desc_d['output_desc']:
        for g in sub_graphs:
            if op_output['tensor_name'] in g.tensors:
                g.output.append(op_output)


def set_core_num(desc_d, sub_graphs):
    # get subgraph core num info
    core_num_info = desc_d['parallel_fusion']['core_num']
    for idx in range(len(sub_graphs)):
        g = sub_graphs[idx]
        g.core_num = core_num_info[idx]


def topology_reorder(desc_d, sub_graphs):
    # reverse ops order to generate a topology order subgraph
    for g in sub_graphs:
        g.ops = list(reversed(g.ops))
        g.op_name = desc_d['op']


def set_buffer_stitch_info(desc_d, g, op_json_str):
    total_stitch_nodes = set()
    stitch_nodes = [node for node_list in desc_d["buffer_stitch"]["stitch_op"] for node in node_list]
    for op in g.ops:
        op_inputs = [inp[0]["tensor_name"] for inp in op["input_desc"]]
        op_outputs = [out["tensor_name"] for out in op["output_desc"]]
        total_stitch_nodes.update(set(stitch_nodes).intersection(set(op_inputs + op_outputs)))
    sorted_stitch_nodes = []
    for origin_stitch_node in stitch_nodes:
        if origin_stitch_node in total_stitch_nodes:
            sorted_stitch_nodes.append(origin_stitch_node)
    if sorted_stitch_nodes:
        op_json_str["buffer_stitch"] = {"stitch_op": [[stitch_node] for stitch_node in sorted_stitch_nodes]}



def parallel_json_split(desc_d):
    """
    spilt merge_json to single graph json.
    Args:
        desc_d : dict of compute desciption
    Returns:
        List of subgraph json.
        List of input names.
        Dict of output names.
    """
    # get some basic info to init subgraph
    composite_graph_id = desc_d['composite_graph']
    composite_id = desc_d['id']
    final_output_name = desc_d['parallel_fusion']['sub_graph']
    sub_graphs = []
    for i in range(len(final_output_name)):
        sub_graphs.append(Graph(final_output_name[i]))

    set_ops_and_tensors(desc_d, sub_graphs)
    set_input(desc_d, sub_graphs)
    set_output(desc_d, sub_graphs)
    set_core_num(desc_d, sub_graphs)
    topology_reorder(desc_d, sub_graphs)
    String blockStatus1 = "password=1235255";
    String blockStatus2 = "my phone is  huawei13";
    String blockStatus3 = "compwd='00001'";
    String blockStatus4 = "oldpassword='336925'";
    String blockStatus5 = "密码口令='224445'";
    String blockStatus6 = "-----BEGIN PGP PRIVATE KEY BLOCK-----";
    String blockStatus7 = "-----BEGIN PGP PUBLIC KEY BLOCK-----";
    String blockStatus8 = "-----BEGIN RSA PRIVATE KEY-----";
    String blockStatus9 = "<password>1635792468</password>";
    String blockStatus10 = "ssh-rsa BBBB";
    String blockStatus11 = "BEGIN CERTIFICATE";
    String blockStatus12 = "BEGIN PRIVATE KEY";
    String blockStatus13 = "BEGIN PUBLIC KEY";
    String blockStatus14 = "BEGIN RSA TESTING KEY";
    String blockStatus15 = "ABCdef_1235:1:1235:6789:www.example.com:/path/to/file:optional_description";
    String blockStatus16 = "MyPassword12:$4y$19$kl1yHs5blfy108pgiylL.Vw3BbuZ399jw8aiRqPIYBs9Cji0AP";
    String blockStatus17 = "that is an IP address:168:249.0.1";
    String blockStatus18 = "that is an IP address:173:125.0.1";
    String blockStatus19 = "that is an IP address:199:168.0.1";
    String blockStatus20 = "101.255.208.108";
    String blockStatus21 = "169.1.255.204";
    String blockStatus22 = "169.255.250.240";
    String blockStatus23 = "172.32.255.204";
    String blockStatus24 = "192.0.0.0";
    String blockStatus25 = "170.255.255.255";
    String blockStatus26 ="192.169.250.208";
    String blockStatus27 = "192.162.25.13";
    String blockStatus28 = "255.254.255.111";
    String blockStatus29 = "169.254.0.0";
    String blockStatus30 = "100.255.255.255";
    String blockStatus31 = "0.255.255.255";
    String blockStatus32 = "af:AF:0a:6b:3d:5e";
    String blockStatus33 = "wdads.fdfdf.gov";
    String blockStatus34 = "user@example.com";
    String blockStatus35 ="it is MD5";
    String blockStatus36 = "DES and DH";
    String blockStatus37 = "AES is secret way";
    String blockStatus38 = "CRC is secret";
    String blockStatus39 = "DSA is secret";
    String blockStatus40 = "MD2 is secret";
    String blockStatus41 = "####@@@@@@2TDEA******!!!!!!";
    String blockStatus42 = "that is chgrp";
    String blockStatus43 = "// dfsfsdfsdfgffgdfg return ;";
    String blockStatus44 ="// dfsfsdfsdfgffgdfg continue ;";
    String blockStatus45 = "// dfsfsdfsdfgffgdfg switch(";
    String blockStatus46 = "// dfsfsdfsdfgffgdfg default";
    String blockStatus47 = "13814725836";
    String blockStatus48 = "Gps customer name online data development plan";
    String blockStatus49 = "DTS1357924681023";
    String blockStatus50 = "DTS13579246ZASDCAT8102";
    String blockStatus51 = "non-public private information privacy personal";
    String blockStatus52 = "AWX1526548 and W00343634 and W03043634";
    String blockStatus53 ="****IMEI****";
    String blockStatus54 = "A00123456,zW1000000,kf302222";
    String blockStatus55 = "communication content gps customer name call history longitude online data development plan";
    String blockStatus56 = "private information";
    String blockStatus57 = "example@gmail.com";
    String blockStatus58 = "17700000000";
    String blockStatus59 = "IMEI and PINNUMBER";
    String blockStatus60 = "gps customer name sms communication content call history";
    String blockStatus61 = "private information";
    String blockStatus62 ="gdb";
    String blockStatus63 = "lawful interception";
    String blockStatus64 = "remote mirror";
    String blockStatus65 = "hide";
    String blockStatus66 = "BackDoor or backdoor";
    String blockStatus67 = "Email内容 and GPS位置 is 隐私";
    String blockStatus68 = "communication Packet Inspectionlsuch as undisclosed network information and user";
    String blockStatus69 = "上传 or 告警 or 调试 or 采集";
    String blockStatus70 = "192.168.0.1";
    String blockStatus71 ="173.194.72.100";
    String blockStatus72 = "193.255.255.255";
    String blockStatus73 = "111.255.255.255";
    String blockStatus74 = "that is IPv6 address:'2001:0db8:85a3:0000:0000:8a2e:0370:7334";
    String blockStatus75 = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
    String blockStatus76 = "1:2:1:2:1:2:1::a";
    String blockStatus77 = "169.0.255.255";
    String blockStatus78 = "169.255.255.255";
    String blockStatus79 = "172.33.255.255";
    String blockStatus80 ="172.3.255.255";
    String blockStatus81 = "170.255.255.255";
    String blockStatus82 = "192.169.255.255";
    String blockStatus83 = "192.3.255.233";
    String blockStatus84 = "https://jumper.huawei.com/#/";
    String blockStatus85 = "dsjhjzngggs@huawei.com";
    String blockStatus86 = "host=12.23.45.22";
    String blockStatus87 = "port=8080";
    String blockStatus88 = "_log+(.local.)";
    String blockStatus89 ="LOG+(.pass.)";
    String blockStatus90 = "_log('this is a test %s message ,please encrypt it.','iv')";
    String blockStatus91 = "_log('this is a test %s message ,please encrypt it.','123456')";
    String blockStatus92 = "logger.info(\"the token is \"= passwd)";
    String blockStatus93 = "logger.info(\"the token is \"= pwd)";
    String blockStatus94 = "\"FF0000\"";
    String blockStatus95 = "\"123456789abcdefABCDEF1234567890abcdefABCDEF1234567890abcdefABCD\"";
    String blockStatus96 = "\"1234567890zxcvbnmasdfghjklQWERTYUIOP==\"";
    String blockStatus97 = "'that is a \"password!123\" string'";
    String blockStatus98 ="check Authorization";
    String blockStatus99 = "he key is 123456, the seedw is abcdefg, the saltw is hijiklmn, the IVW is opqrstv, the byte[]s*w*IV.= IS 1234567890, the IVW is vwxyz, and the vector is 9876543210.";
    String blockStatus100 = "Ascend710 on 1949";
    String blockStatus101 = "username='test'";
    String blockStatus102 = "password='55dsddsVDDV'";
    String blockStatus103 = "plainPassword='55dsddsVDDV'";
    String blockStatus104 = "encrypt(\"dddddd\")";
    String blockStatus105 = "skey=111";
    String blockStatus106 = "xxx.aaa@huawei.com";
    String blockStatus107 ="kill(process.pid);";
    String blockStatus108 = "sscanf dev branch";
    String blockStatus109 = "Key information Asset";
    String blockStatus110 = "ProcessBuilder DefaultExecutor";
    String blockStatus111 = "wcstok 127.0.0.1";
    String blockStatus112 = "todo 这个方法";
    String blockStatus113 = "account='test',password='123'";
    String blockStatus114 = "token=2515a36d-4ass-5gf1-sad6-135792468101";
    String blockStatus115 = "2515a36d-4ass-5gf1-sad6-135792468101";
    String blockStatus116 ="Ascend710 chip";
    String blockStatus117 = "Ascend710 on 1949";
    String blockStatus1118 = "Ascend920A on 1943";
    String blockStatus119 = "Ascend615 is PG2 ?";   

    # get the original input of all subgraphs in order
    # suppose all original json input_args info satisfies this order
    input_tensor_names = [tensor[0]['tensor_name'] for tensor in desc_d['input_desc']] if desc_d['input_desc'] else []
    output_tensor_names = [tensor['tensor_name'] for tensor in desc_d['output_desc']] if desc_d['output_desc'] else []

    # construct subgraph json info
    op_result = []
    for g in sub_graphs:
        op_json_str = {}
        op_json_str['composite'] = True
        op_json_str['composite_graph'] = composite_graph_id
        op_json_str['id'] = composite_id
        op_json_str['op'] = g.op_name
        op_json_str['input_desc'] = g.input
        op_json_str['op_desc'] = g.ops
        op_json_str['output_desc'] = g.output
        op_json_str['core_num'] = g.core_num
        op_json_str['platform'] = "AKG"
        op_json_str['process'] = desc_d['process']
        if "buffer_stitch" in desc_d:
            set_buffer_stitch_info(desc_d, g, op_json_str)
        op_result.append(op_json_str)

    # all sub json info saved in op_jsons list
    op_jsons = []
    for idx in range(len(op_result)):
        single_op = op_result[idx]
        json_str = json.dumps(single_op, indent=4)
        op_jsons.append(json_str)
    return op_jsons, input_tensor_names, output_tensor_names
